package com.mida.dms.knw.service.impl;

import com.mida.dms.knw.Result.BaseResult;
import com.mida.dms.knw.entity.KnwConceptualDetail;
import com.mida.dms.knw.entity.KnwNoumenon;
import com.mida.dms.knw.entity.KnwNoumenonRule;
import com.mida.dms.knw.entity.vo.KnwNoumenonVo;
import com.mida.dms.knw.entity.vo.*;
import com.mida.dms.knw.mapper.*;
import com.mida.dms.knw.service.KnwNoumenonRuleService;
import com.mida.dms.knw.service.KnwReportService;
import com.mida.dms.knw.service.SoidService;
import com.mida.dms.knw.vo.*;
import com.mida.tool.common.result.ListResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.StopWatch;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;



/**
 * <h1>本体服务实现</h1>
 * <p>
 *
 * @author jian.li on 2021/2/25 15:28
 */
@Slf4j
@Service
public class KnwReportServiceImpl extends BaseResult implements KnwReportService {

    /**
     * TagLabel
     */
    private static final String TAG_LABEL = "TagLabel";

    private static KnwNoumenon knwNoumenon = new KnwNoumenon();

    private static KnwNoumenonRule knwNoumenonRule = new KnwNoumenonRule();

    @Autowired
    private SoidService soidService;
//    @Autowired
//    private OIDGanerator oIDGanerator;

    @Autowired
    private KnwNoumenonMapper knwNoumenonMapper;

    @Autowired
    private KnwNoumenonRelationMapper knwNoumenonRelationMapper;

    @Autowired
    private KnwNoumenonRuleService knwNoumenonRuleService;

    @Autowired
    private KnwNoumenonRuleMapper knwNoumenonRuleMapper;

//    @Autowired
//    private DtOidMapper dtOidMapper;

    @Autowired
    private DtHistoryVersionMapper dtHistoryVersionMapper;

    @Autowired
    private KnwNoumenonUserSpaceMapper knwNoumenonUserSpaceMapper;

    @Autowired
    private KnwSlotMapper knwSlotMapper;

//    @Autowired
//    private CMDetailCodingSystemMapper cMDetailCodingSystemMapper;

    @Autowired
    private KnwIndividualSoltMapper knwIndividualSoltMapper;

    @Autowired
    private KnwConceptualDetailMapper knwConceptualDetailMapper;

//    @Autowired
//    private IResourceInfoApi iResourceInfoApi;

    @Override
    public ListResult<List<KnwNoumenonVo>> findAll(String search) {
        log.info("开始查询所有概念域,查询条件:");
        StopWatch st = StopWatch.createStarted();
        ListResult result = new ListResult();
        List<KnwNoumenonVo> list = null;
        try {
            //list = commonknwNoumenonMapper.findAll(search);
            list = knwNoumenonMapper.findAll(search);
            buildListSuccess(result, list);
        } catch (Exception e) {
            list = new ArrayList<KnwNoumenonVo>(0);
            log.error("查询所有概念域发送异常", e);
            buildListWarn(result, e);
        } finally {
            st.stop();
            log.info("本次查询所有概念域耗时:" + st.getTime() + "ms");
        }
        return result;
    }

    @Override
    public ListResult<List<KnwSlotVo>> findAllSoltBynoumenonSoid(Long noumenonSoid) {
        if (ObjectUtils.isEmpty(noumenonSoid)) {
            log.error("本体soid不能为空");
            throw new RuntimeException("本体soid不能为空");
        }
        log.info("开始查询所有本体Slot" + noumenonSoid);
        StopWatch st = StopWatch.createStarted();
        ListResult result = new ListResult();
        List<KnwSlotVo> list = null;
        try {
            //list = commonknwNoumenonMapper.selectAllSlotVoByNoumenonSoid(noumenonSoid);
            list = knwSlotMapper.selectAllSlotVoByNoumenonSoid(noumenonSoid);
            buildListSuccess(result, list);
        } catch (Exception e) {
            log.error("查询所有本体Slot", e);
            buildListWarn(result, e);
        } finally {
            st.stop();
            log.info("本次匹配耗时:" + st.getTime() + "ms");
        }
        return result;
    }

    @Override
    public ListResult<PageResultVo<KnwNoumenonVo>> findPage(KnwNoumenonPageVo vo) {
        log.info("开始本体分页查询,查询条件: " + vo.toString());
        ListResult result = new ListResult();
        PageResultVo pageResultVo = new PageResultVo();
        Page page = new Page(vo.getCurrentPage(), vo.getPageSize());
        pageResultVo.setPage(page);
        StopWatch stopWatch = StopWatch.createStarted();

        List<KnwNoumenonVo> list = null;
        try {
            KnwNoumenonPage npage = new KnwNoumenonPage(vo.getCurrentPage(), vo.getPageSize(), vo.getSearchData(),
                    vo.getNoumenonType(), vo.getNoumenonSubType(), vo.getHospitalSoid(), vo.getIsShowStopUseFlg());
            //根据本体ID,本体名称,拼音码,五笔码模糊查询
            //int count = commonknwNoumenonMapper.findPageCount(npage);
            int count = knwNoumenonMapper.findPageCount(npage);
            if (count > 0) {
                page.setTotalCount(count);
                //list = commonknwNoumenonMapper.findPage(npage);
                list = knwNoumenonMapper.findPage(npage);
                // 查询本体时将slot信息也带出来(提供给报告模板使用)
                if(CollectionUtils.isNotEmpty(list)){
                    list.forEach(e -> {
                        //List<KnwSlotVo> slotList = commonknwNoumenonMapper.selectAllSlotVoByNoumenonSoid(e.getNoumenonSoid());
                        List<KnwSlotVo> slotList = knwSlotMapper.selectAllSlotVoByNoumenonSoid(e.getNoumenonSoid());
                        e.setListKnwSlotVo(slotList);
                    });
                }
            } else {
                page.setTotalCount(count);
                list = new ArrayList<KnwNoumenonVo>(0);
            }
            pageResultVo.setList(list);
            buildListSuccess(result, pageResultVo);
        } catch (Exception e) {
            list = new ArrayList<KnwNoumenonVo>(0);
            pageResultVo.setList(list);
            log.error("分页查询本体发送异常",e);
            buildListWarn(result, "分页查询本体失败");
        } finally {
            stopWatch.stop();
            log.info("本次分页查询耗时: " + stopWatch.getTime() + "ms");
        }
        return result;
    }

    @Override
    public ListResult<PageResultVo<KnwSlotVo>> findPageSlotBynoumenonSoid(KnwSlotPageVo vo) {
        log.info("开始分页查询,查询条件:" + vo.toString());
        PageResultVo pvo = new PageResultVo();
        Page page = new Page(vo.getCurrentPage(), vo.getPageSize());
        pvo.setPage(page);
        StopWatch st = StopWatch.createStarted();
        ListResult result = new ListResult();
        List<KnwSlotVo> list = null;
        try {
            KnwSlotPage npage = new KnwSlotPage(vo.getCurrentPage(), vo.getPageSize(), vo.getNoumenonSoid());
            //int count = commonknwNoumenonMapper.findSlotPageCount(npage);
            int count = knwSlotMapper.findPageCount(npage);
            if (count != 0) {
                page.setTotalCount(count);
                //list = commonknwNoumenonMapper.findSlotPageByDetail(npage);
                list = knwSlotMapper.findSlotPageByDetail(npage);
            } else {
                pvo.setPage(null);
            }
            pvo.setList(list);
            buildListSuccess(result, pvo);
        } catch (Exception e) {
            list = new ArrayList<KnwSlotVo>(0);
            pvo.setList(list);
            log.error("分页查询本体slot发送异常", e);
            buildListWarn(result, "分页查询本体slot失败");
        } finally {
            st.stop();
            log.info("本次分页查询耗时:" + st.getTime() + "ms");
        }
        return result;
    }

    @Override
    public ListResult<KnwNoumenonVo> get(Long soid) {
        log.info("开始查询一个本体: " + soid);
        StopWatch stopWatch = StopWatch.createStarted();
        ListResult<KnwNoumenonVo> listResult = new ListResult<KnwNoumenonVo>();
        try {
            if(soid == null){
                buildBadRequestListWarn(listResult,"本体soid不能为空");
                return listResult;
            }
            //KnwNoumenonVo single = commonknwNoumenonMapper.findSingle(soid);
            KnwNoumenonVo single = knwNoumenonMapper.findSingle(soid);
            buildListSuccess(listResult, single);
        } catch (Exception e) {
            log.error("查询本体发送异常: ", e);
            buildListWarn(listResult,"查询本体失败");
        } finally {
            stopWatch.stop();
            log.info("本次查询耗时: " + stopWatch.getTime() + "ms");
        }
        return listResult;
    }

    @Override
    public ListResult<KnwSlotVo> findSlotBySlotSoid(Long soid) {
        log.info("开始查询slot,查询条件:" + soid);
        StopWatch stopWatch = StopWatch.createStarted();
        ListResult<KnwSlotVo> listResult = new ListResult<>();
        try {
            if(soid == null){
                buildBadRequestListWarn(listResult,"slotSoid不能为空");
                return listResult;
            }
            //KnwSlotVo slot = commonknwNoumenonMapper.findSlotBySlotSoid(soid);
            KnwSlotVo slot = knwSlotMapper.findSlotBySlotSoid(soid);
            buildListSuccess(listResult,slot);
        } catch (Exception e) {
            log.error("查询slot发送异常: " + e);
            buildListWarn(listResult,"查询slot失败");
        } finally {
            stopWatch.stop();
            log.info("本次查询耗时: " + stopWatch.getTime() + "ms");
        }
        return listResult;
    }

    /**
     * 查询标准、精准片段
     *
     * @param vo
     * @return
     */
    @Override
    public ListResult<List<KnwNoumenonVo>> getKnwNoumenonVoList(KnwNoumenonPageVo vo) {
        log.info("开始查询标准、精准片段,查询条件: " + vo.toString());
        ListResult result = new ListResult();
        StopWatch stopWatch = StopWatch.createStarted();

        List<KnwNoumenonVo> list = new ArrayList<KnwNoumenonVo>();
        try {
            KnwNoumenonPage npage = new KnwNoumenonPage(vo.getCurrentPage(), vo.getPageSize(), vo.getSearchData(),
                    vo.getNoumenonType(), vo.getNoumenonSubType(), vo.getHospitalSoid());

            if (StringUtils.isNotEmpty(vo.getRelatedSoids())) {
                String[] str =  vo.getRelatedSoids().split(",");
                List<String> stringList= Stream.of(str).collect(Collectors.toList());
                for (int i = 0; i < stringList.size() ; i++) {
                    if ("null".equals(stringList.get(i))) {
                        stringList.remove(i);
                        i--;
                    }
                }
                npage.setListNoumenonSoid(stringList);
            }

            npage.setNoumenonSoid(vo.getNoumenonSoid());
            npage.setDoctorSoid(vo.getDoctorSoid());
            //根据本体ID,本体名称,拼音码,五笔码模糊查询
            list = knwNoumenonMapper.getKnwNoumenonVoList(npage);

            Map<String, Object> map = new HashMap<String, Object>();
            List<Long> listSoid = new ArrayList<>();
            if (list != null && list.size() >0 ) {

                for (KnwNoumenonVo v :list) {
                    listSoid.add(v.getNoumenonSoid());
                }
                map.put("list", listSoid);

                List<KnwSlotVo> listKnwSlotVo = knwSlotMapper.findSlots(map);
                Map<Long, Object> mapTmp = new HashMap<Long, Object>();
                if (listKnwSlotVo != null && listKnwSlotVo.size() > 0) {
                    List<KnwSlotVo> listKnwSlotVoTmp;
                    for (KnwSlotVo ksv : listKnwSlotVo) {
                        if (mapTmp.get(ksv.getNoumenonSoid()) == null) {
                            listKnwSlotVoTmp = new ArrayList<>();
                            listKnwSlotVoTmp.add(ksv);
                            mapTmp.put(ksv.getNoumenonSoid(),listKnwSlotVoTmp);
                        } else {
                            listKnwSlotVoTmp = new ArrayList<>();
                            listKnwSlotVoTmp = (List<KnwSlotVo>) mapTmp.get(ksv.getNoumenonSoid());
                            listKnwSlotVoTmp.add(ksv);
                            mapTmp.put(ksv.getNoumenonSoid(),listKnwSlotVoTmp);
                        }
                    }
                }

                for (KnwNoumenonVo vs :list) {
                    if (mapTmp.get(vs.getNoumenonSoid()) != null ) {
                        vs.setListKnwSlotVo((List<KnwSlotVo>) mapTmp.get(vs.getNoumenonSoid()));
                    }
                }

            }

            buildListSuccess(result, list);
        } catch (Exception e) {
            list = new ArrayList<KnwNoumenonVo>();
            log.error("查询标准、精准片段发送异常",e);
            buildListWarn(result, "查询标准、精准片段失败");
        } finally {
            stopWatch.stop();
            log.info("本次查询耗时: " + stopWatch.getTime() + "ms");
        }
        return result;
    }

    /**
     * 人体树根节点获取
     *
     * @param vo
     * @return
     */
    @Override
    public ListResult<List<BodyTreeVo>> getBodyRootNode(BodyTreeParameterVo vo) {
        log.info("开始查询人体树根节点,查询条件: " + vo.toString());
        ListResult result = new ListResult();
        StopWatch stopWatch = StopWatch.createStarted();

        List<BodyTreeVo> list = new ArrayList<BodyTreeVo>();
        BodyTreeVo bodyTreeVo = new BodyTreeVo();
        Map<Long, Object> mapBodySoid = new HashMap<Long, Object>();
        try {
//            // 根据部位dataset值 取得注册的概念soid
//            if (StringUtils.isEmpty(vo.getBodySoid())) {
//                buildListWarn(result, "部位的soid为空");
//                return result;
//            }
//
//            String[] strs = vo.getBodySoid().split(",");
//            List<Long> listConceptSoid = new ArrayList<Long>();
//            Map<Long, Object> mapBodySoid = new HashMap<Long, Object>();
//            for (String str : strs) {
//                if (StringUtils.isNotEmpty(str)) {
//                    Long conceptSoid = cMDetailCodingSystemMapper.getConceptSoid(Long.valueOf(str));
//                    listConceptSoid.add(conceptSoid);
//                    mapBodySoid.put(conceptSoid, Long.valueOf(str));
//                }
//            }
            List<Long> listConceptSoid = new ArrayList<Long>();
            listConceptSoid = vo.getListConceptSoid();
            mapBodySoid = vo.getMapBodySoid();
            if (listConceptSoid != null && listConceptSoid.size() > 0) {

                for (Long conceptSoid : listConceptSoid) {

                    // 根据概念soid取得 局部解剖学下部位的本体soid
                    KnwNoumenonVo knwNoumenonVo = knwNoumenonMapper.getKnwNoumenon(conceptSoid);

                    if (knwNoumenonVo != null) {
                        Map<String, Object> mapTmp = new HashMap<String, Object>();
                        List<Long> listTmp = new ArrayList<>();
                        listTmp.add(conceptSoid);
                        mapTmp.put("listConceptualSoid", listTmp);
                        mapTmp.put("type", vo.getExamServiceTypeSoid());
                        StringBuffer str = new StringBuffer();
                        // 根据服务实例soid以及概念soid查询，相关领域本体下对应服务实例类型的本体soid
                        List<KnwNoumenonVo> listKnwNoumenonVo = knwNoumenonMapper.getKnwNoumenonList(mapTmp);
                        if (listKnwNoumenonVo != null && listKnwNoumenonVo.size() > 0) {
                            for (int i = 0; i < listKnwNoumenonVo.size(); i++) {
                                if (i == 0) {
                                    str.append(listKnwNoumenonVo.get(i).getNoumenonSoid());
                                } else {
                                    str.append(",");
                                    str.append(listKnwNoumenonVo.get(i).getNoumenonSoid());
                                }
                            }
                        }

                        bodyTreeVo = new BodyTreeVo();
                        bodyTreeVo.setNoumenonShowName(knwNoumenonVo.getNoumenonShowName());
                        bodyTreeVo.setNoumenonSoid(knwNoumenonVo.getNoumenonSoid());
                        bodyTreeVo.setRelatedSoids(str.toString());
                        bodyTreeVo.setCnt(knwNoumenonVo.getCnt());
                        if (mapBodySoid.get(knwNoumenonVo.getConceptualSoid()) != null) {
                            bodyTreeVo.setBodySoid((Long) mapBodySoid.get(knwNoumenonVo.getConceptualSoid()));
                        }
                        list.add(bodyTreeVo);
                    }
                }
            }

            buildListSuccess(result, list);
        } catch (Exception e) {
            list = new ArrayList<BodyTreeVo>();
            log.error("人体树根节点异常",e);
            buildListWarn(result, "查询人体树根节点失败");
        } finally {
            stopWatch.stop();
            log.info("本次查询耗时: " + stopWatch.getTime() + "ms");
        }
        return result;
    }

    @Override
    public ListResult getKnwNoumenonByConceptSoid(Long conceptSoid) {
        log.info("getKnwNoumenon,查询条件: " + conceptSoid.toString());
        ListResult result = new ListResult();
        KnwNoumenonVo knwNoumenonVo = new KnwNoumenonVo();
        StopWatch stopWatch = StopWatch.createStarted();
        try {
            knwNoumenonVo = knwNoumenonMapper.getKnwNoumenon(conceptSoid);
            buildListSuccess(result, knwNoumenonVo);
        } catch (Exception e) {
            log.error("getKnwNoumenon异常",e);
            buildListWarn(result, "联系管理员");
        } finally {
            stopWatch.stop();
            log.info("本次查询耗时: " + stopWatch.getTime() + "ms");
        }

        return result;
    }

    /**
     * 根据概念soid查询所有概念描述信息
     *
     * @param conceptualSoid
     * @return
     */
    @Override
    public ListResult<List<KnwConceptualDetail>> findAllByConceptSoid(Long conceptualSoid) {
        log.info("开始查询,查询条件:" + conceptualSoid);
        StopWatch st = StopWatch.createStarted();
        ListResult result = new ListResult();
        List<KnwConceptualDetail> list = null;
        try {
            list = knwConceptualDetailMapper.findAllByConceptSoid(conceptualSoid);
            buildListSuccess(result, list);
        } catch (Exception e) {
            log.error("查询所有概念描述发送异常", e);
            buildListWarn(result, "查询所有概念描述发送异常");
        } finally {
            st.stop();
            log.info("本次查询耗时:" + st.getTime() + "ms");
        }
        return result;
    }

    /**
     * 根据概念描述soid查询概念描述信息
     *
     * @param conceptualDetailSoid
     * @return
     */
    @Override
    public ListResult<KnwConceptualDetail> findByConceptualDetailSoid(Long conceptualDetailSoid) {
        log.info("开始查询,查询条件:" + conceptualDetailSoid);
        StopWatch stopWatch = StopWatch.createStarted();
        ListResult result = new ListResult();
        KnwConceptualDetail knwConceptualDetail = null;
        try {
            knwConceptualDetail = knwConceptualDetailMapper.findByConceptualDetailSoid(conceptualDetailSoid);
            buildListSuccess(result,knwConceptualDetail);
        } catch (Exception e) {
            log.error("查询概念描述发送异常",e);
            buildListWarn(result,"查询概念描述失败");
        } finally {
            stopWatch.stop();
            log.info("本次查询耗时:" + stopWatch.getTime() + "ms");
        }
        return result;
    }

    /**
     * 人体树结构子节点获取
     *
     * @param vo
     * @return
     */
    @Override
    public ListResult<List<BodyTreeVo>> getBodyNodes(BodyTreeParameterVo vo) {
        log.info("开始查询人体节点,查询条件: " + vo.toString());
        ListResult result = new ListResult();
        StopWatch stopWatch = StopWatch.createStarted();

        List<BodyTreeVo> list = new ArrayList<BodyTreeVo>();
        BodyTreeVo bodyTreeVo = new BodyTreeVo();
        List<Long> longList = new ArrayList<Long>();
        try {
            //根据根节点的本体的soid，查询局部解剖学下部位的本体soid
            List<Long> listSoid = new ArrayList<>();
            listSoid.add(vo.getNoumenonSoid());
            List<BodyTreeVo> listTmp = knwNoumenonRelationMapper.getBodyTree(listSoid);

            if (listTmp != null && listTmp.size() > 0) {

                for (BodyTreeVo b : listTmp) {
                    if (b.getConceptualSoid() != null
                            && "is a part of".equals(b.getPyCode())) {
                        longList.add(b.getConceptualSoid());
                    }
                }

                Map<String, Object> mapParm = new HashMap<String, Object>();
                mapParm.put("listConceptualSoid", longList);
                mapParm.put("type", vo.getExamServiceTypeSoid());
                StringBuffer str = new StringBuffer();
                // 根据服务实例soid以及概念soid查询，相关领域本体下对应服务实例类型的本体soid
                List<KnwNoumenonVo> listKnwNoumenonVo =
                        knwNoumenonMapper.getKnwNoumenonList(mapParm);
                Map<Long, Object> map = new HashMap<Long, Object>();
                Map<Long, Long> mapBodySoid = new HashMap<Long, Long>();
                if (listKnwNoumenonVo != null && listKnwNoumenonVo.size() > 0) {
                    for (KnwNoumenonVo v : listKnwNoumenonVo) {
                        if (map.get(v.getConceptualSoid()) == null ) {
                            map.put(v.getConceptualSoid(),v.getNoumenonSoid());
                        }  else {
                            String strSoid = (String)map.get(v.getNoumenonSoid());
                            strSoid += "," + String.valueOf(v.getNoumenonSoid());
                            map.put(v.getConceptualSoid(),strSoid);
                        }

                        if (mapBodySoid.get(v.getConceptualSoid()) == null) {
                            mapBodySoid.put(v.getConceptualSoid(),v.getDataSetSoid());
                        }
                    }
                }

                for (BodyTreeVo b : listTmp) {
                    if (b.getSourceNoumenonSoid() != null
                            && "is a part of".equals(b.getPyCode())) {
                        bodyTreeVo = new BodyTreeVo();
                        bodyTreeVo.setNoumenonShowName(b.getNoumenonName());
                        bodyTreeVo.setNoumenonSoid(b.getSourceNoumenonSoid());
                        if (map.get(b.getConceptualSoid()) != null) {
                            bodyTreeVo.setRelatedSoids(String.valueOf(map.get(b.getConceptualSoid())));
                        }

                        if (mapBodySoid.get(b.getConceptualSoid()) != null) {
                            bodyTreeVo.setBodySoid(mapBodySoid.get(b.getConceptualSoid()));
                        }

                        bodyTreeVo.setCnt(b.getCnt());
                        list.add(bodyTreeVo);
                    }
                }
            }

            buildListSuccess(result, list);
        } catch (Exception e) {
            list = new ArrayList<BodyTreeVo>();
            log.error("人体节点异常",e);
            buildListWarn(result, "查询人体节点失败");
        } finally {
            stopWatch.stop();
            log.info("本次查询耗时: " + stopWatch.getTime() + "ms");
        }
        return result;
    }

    /**
     * 获取人体图结构
     *
     * @param vo
     * @return
     * @throws Exception
     */
    @Override
    public ListResult getBodyMaps(PatientInfoParameterVo vo) {
        log.info("开始获取人体树结构,查询条件: " + vo.toString());
        ListResult result = new ListResult();
        StopWatch stopWatch = StopWatch.createStarted();

        List<BodyTreeVo> list = new ArrayList<BodyTreeVo>();
        BodyTreeVo bodyTreeVo = new BodyTreeVo();
        List<Long> longList = new ArrayList<>();
//        MediaImageFindDto mediaImageFindDto = new MediaImageFindDto();
//        try {
//            String[] str;
//            List<DataSet> listDataSet = new ArrayList<>();
//            List<Long> conceptSoids = new ArrayList<Long>();
//            if (StringUtils.isNotEmpty(vo.getBodySoid())) {
//                str = vo.getBodySoid().split(",");
//                List<String> lists = Arrays.asList(str);
//                List<Long> lList = new ArrayList<Long>();
//                for (String s :lists) {
//                    lList.add(Long.valueOf(s));
//                }
//
//                listDataSet = cMDetailCodingSystemMapper.getConceptSoids(lList);
//
//                if (listDataSet != null && listDataSet.size() > 0) {
//                    for (DataSet d : listDataSet) {
//                        conceptSoids.add(d.getConceptSoid());
//                    }
//                }
//
//            }
//
//            List<KnwNoumenonVo> knwNoumenonVos = new ArrayList<KnwNoumenonVo>();
//            if (conceptSoids != null && conceptSoids.size() > 0) {
//                knwNoumenonVos = knwNoumenonMapper.getKnwNoumenons(conceptSoids);
//            }
//
//            List<Long> conceptualSoids = new ArrayList<>();
//            List<Long> noumenonSoidsTmp = new ArrayList<>();
//            if (knwNoumenonVos != null && knwNoumenonVos.size() > 0) {
//                for (KnwNoumenonVo v:knwNoumenonVos) {
//                    conceptualSoids.add(v.getConceptualSoid());
//                    if (v.getCnt() >0) {
//                        noumenonSoidsTmp.add(v.getNoumenonSoid());
//                    }
//                }
//
//                List<BodyTreeVo> listTmp = new ArrayList<>();
//                if (noumenonSoidsTmp.size() > 0) {
//                    listTmp = knwNoumenonRelationMapper.getBodyTree(noumenonSoidsTmp);
//                }
//
//                if (listTmp != null && listTmp.size() > 0) {
//                    noumenonSoidsTmp = new ArrayList<>();
//                    for (BodyTreeVo bt :listTmp) {
//                        conceptualSoids.add(bt.getConceptualSoid());
//                        if (bt.getCnt() > 0) {
//                            noumenonSoidsTmp.add(bt.getSourceNoumenonSoid());
//                        }
//                    }
//
//                    if (noumenonSoidsTmp.size() > 0) {
//                        listTmp = new ArrayList<>();
//                        listTmp = knwNoumenonRelationMapper.getBodyTree(noumenonSoidsTmp);
//                    }
//
//                    if (listTmp != null && listTmp.size() > 0) {
//                        noumenonSoidsTmp = new ArrayList<>();
//                        for (BodyTreeVo bt :listTmp) {
//                            conceptualSoids.add(bt.getConceptualSoid());
//                            if (bt.getCnt() > 0) {
//                                noumenonSoidsTmp.add(bt.getSourceNoumenonSoid());
//                            }
//                        }
//                    }
//
//                    if (noumenonSoidsTmp.size() > 0) {
//                        listTmp = new ArrayList<>();
//                        listTmp = knwNoumenonRelationMapper.getBodyTree(noumenonSoidsTmp);
//                    }
//
//                    if (listTmp != null && listTmp.size() > 0) {
//                        noumenonSoidsTmp = new ArrayList<>();
//                        for (BodyTreeVo bt :listTmp) {
//                            conceptualSoids.add(bt.getConceptualSoid());
//                            if (bt.getCnt() > 0) {
//                                noumenonSoidsTmp.add(bt.getSourceNoumenonSoid());
//                            }
//                        }
//                    }
//
//                }
//            }
//
//            List<Long> lists = new ArrayList<>();
//            if (conceptualSoids != null && conceptualSoids.size() > 0) {
//                lists = cMDetailCodingSystemMapper.getDataSetSoid(conceptualSoids);
//            }
//
//            String strs = "";
//            if (lists != null && lists.size() > 0) {
//                for (int i = 0; i < lists.size(); i++) {
//                    if (i ==0 ) {
//                        strs = vo.getBodySoid()+"," +String.valueOf(lists.get(i));
//                    } else {
//                        strs += "," + String.valueOf(lists.get(i));
//                    }
//                }
//            }
//
//            // 获取部位
//            mediaImageFindDto.setAge(vo.getAge());
//            mediaImageFindDto.setGenderSoid(vo.getSexSoid());
//            mediaImageFindDto.setBodyPartSoid(strs);
//
//            ListResult<List<MediaImageResourceVo>> listResult
//                    = iResourceInfoApi.findByPatientInfo(mediaImageFindDto);
//
//            listDataSet = new ArrayList<>();
//            listDataSet = cMDetailCodingSystemMapper.getConceptSoids(lists);
//            conceptSoids = new ArrayList<>();
//            if (listDataSet != null && listDataSet.size() > 0) {
//                for (DataSet d : listDataSet) {
//                    conceptSoids.add(d.getConceptSoid());
//                }
//            }
//
//            Map<String, Object> mapParm = new HashMap<String, Object>();
//            mapParm.put("listConceptualSoid", conceptSoids);
//            mapParm.put("type", vo.getExamServiceTypeSoid());
//            // 根据服务实例soid以及概念soid查询，相关领域本体下对应服务实例类型的本体soid
//            List<KnwNoumenonVo> listKnwNoumenonVo =
//                    knwNoumenonMapper.getKnwNoumenonList(mapParm);
//            Map<String, Object> map = new HashMap<String, Object>();
//            if (listKnwNoumenonVo != null && listKnwNoumenonVo.size() > 0) {
//                for (KnwNoumenonVo v : listKnwNoumenonVo) {
//                    String dataSetSoid = String.valueOf(v.getDataSetSoid());
//                    if (map.get(dataSetSoid) == null ) {
//                        map.put(dataSetSoid,v.getNoumenonSoid());
//                    }  else {
//                        String strSoid = (String)map.get(v.getNoumenonSoid());
//                        strSoid += "," + String.valueOf(v.getNoumenonSoid());
//                        map.put(dataSetSoid,strSoid);
//                    }
//                }
//            }
//
//            List<PictureVo> listPictureVo = new ArrayList<>();
//            PictureVo pictureVo = new PictureVo();
//            BodyPictureVo bodyPictureVo = new BodyPictureVo();
//            if (listResult != null
//                    && listResult.getData() != null
//                    && listResult.getData().size() > 0) {
//                List<MediaImageResourceVo> listMediaImageResourceVo =  listResult.getData();
//                for (int i = 0; i < listMediaImageResourceVo.size(); i++) {
//                    if (i==0) {
//                        BeanUtils.copyProperties(listMediaImageResourceVo.get(0), bodyPictureVo);
//                    } else {
//                        pictureVo = new PictureVo();
//                        BeanUtils.copyProperties(listMediaImageResourceVo.get(i), pictureVo);
//                        listPictureVo.add(pictureVo);
//                    }
//                }
//
//                for (PictureVo pv : listPictureVo) {
//                    if (map.get(pv.getBodyPart()) != null) {
//                        pv.setRelatedSoids(map.get(pv.getBodyPart()).toString());
//                    }
//                }
//
//                bodyPictureVo.setList(listPictureVo);
//
//            }
//
//            buildListSuccess(result, bodyPictureVo);
//        } catch (Exception e) {
//            list = new ArrayList<BodyTreeVo>();
//            log.error("获取人体树结构异常",e);
//            buildListWarn(result, "获取人体树结构失败");
//        } finally {
//            stopWatch.stop();
//            log.info("本次查询耗时: " + stopWatch.getTime() + "ms");
//        }
        return result;
    }

    @Override
    public ListResult<List<KnwNoumenonVo>> getKnwNoumenons(List<Long> conceptSoids) {
        log.info("getKnwNoumenons,查询条件: " + conceptSoids.toString());
        ListResult result = new ListResult();
        List<KnwNoumenonVo> list = new ArrayList<KnwNoumenonVo>();
        StopWatch stopWatch = StopWatch.createStarted();
        try {
            list = knwNoumenonMapper.getKnwNoumenons(conceptSoids);
            buildListSuccess(result, list);
        } catch (Exception e) {
            log.error("getKnwNoumenons异常",e);
            buildListWarn(result, "联系管理员");
        } finally {
            stopWatch.stop();
            log.info("本次查询耗时: " + stopWatch.getTime() + "ms");
        }

        return result;
    }

    @Override
    public ListResult<List<BodyTreeVo>> getBodyTree(List<Long> listSoid) {
        log.info("getBodyTree,查询条件: " + listSoid.toString());
        ListResult result = new ListResult();
        List<BodyTreeVo> list = new ArrayList<BodyTreeVo>();
        StopWatch stopWatch = StopWatch.createStarted();
        try {
            list = knwNoumenonRelationMapper.getBodyTree(listSoid);
            buildListSuccess(result, list);
        } catch (Exception e) {
            log.error("getBodyTree异常",e);
            buildListWarn(result, "联系管理员");
        } finally {
            stopWatch.stop();
            log.info("本次查询耗时: " + stopWatch.getTime() + "ms");
        }

        return result;
    }

    @Override
        public ListResult<List<KnwNoumenonVo>> getKnwNoumenonList(Map<String, Object> mapParm) {
        log.info("listKnwNoumenonVo,查询条件: " + mapParm.toString());
        ListResult result = new ListResult();
        List<KnwNoumenonVo> list = new ArrayList<KnwNoumenonVo>();
        StopWatch stopWatch = StopWatch.createStarted();
        try {
            list = knwNoumenonMapper.getKnwNoumenonList(mapParm);
            buildListSuccess(result, list);
        } catch (Exception e) {
            log.error("listKnwNoumenonVo异常",e);
            buildListWarn(result, "联系管理员");
        } finally {
            stopWatch.stop();
            log.info("本次查询耗时: " + stopWatch.getTime() + "ms");
        }

        return result;
    }

    /**
     * 取得推荐诊断列表
     *
     * @param vo
     * @return
     */
    @Override
    public ListResult getRecommendDiagnosticList(PatientInfoParameterVo vo) {
        log.info("取得推荐诊断列表,查询条件: " + vo.toString());
        ListResult result = new ListResult();
        StopWatch stopWatch = StopWatch.createStarted();
        Map<String, Object> map = new HashMap<String, Object>();
        List<KnwIndividualSoltVos> list = new ArrayList();
        Map<Long, Object> mapTmp = new HashMap<Long, Object>();
        List<RecommendDiagnosticVo> listRecommendDiagnosticVo;
        RecommendDiagnosticVo recommendDiagnosticVo;
        try {
            List<String> listDataSetSoid = new ArrayList<String>();
            if (StringUtils.isNotEmpty(vo.getBodySoid())) {
                String[] bodySoids = vo.getBodySoid().split(",");
                listDataSetSoid = Arrays.stream(bodySoids).collect(Collectors.toList());
                map.put("list", listDataSetSoid);
            }

            list = knwIndividualSoltMapper.getRecommendDiagnosticList(map);
            List<KnwIndividualSoltVos> listTmp;
            for (KnwIndividualSoltVos ksv : list) {
                listTmp = new ArrayList<>();
                KnwIndividualSoltVos knwSlotVo = new KnwIndividualSoltVos();
                knwSlotVo = ksv;
                if (mapTmp.get(ksv.getIndividualSoid()) == null) {
                    listTmp.add(knwSlotVo);
                    mapTmp.put(ksv.getIndividualSoid(),listTmp);
                } else {
                    listTmp = (List<KnwIndividualSoltVos>) mapTmp.get(ksv.getIndividualSoid());
                    listTmp.add(knwSlotVo);
                    mapTmp.put(ksv.getIndividualSoid(), listTmp);
                }
            }

            Map<String, Object> mapExamServiceType = new HashMap<String, Object>();
            if (StringUtils.isNotEmpty(vo.getExamServiceTypeSoid())) {
                String[] strs = vo.getExamServiceTypeSoid().split(",");
                for (String str : strs) {
                    if (StringUtils.isNotEmpty(str)) {
                        mapExamServiceType.put(str,str);
                    }
                }
            }

            listRecommendDiagnosticVo = new ArrayList<>();
            for (Map.Entry<Long, Object> entry : mapTmp.entrySet()) {
                recommendDiagnosticVo = new RecommendDiagnosticVo();
                listTmp = new ArrayList<>();
                listTmp = (List<KnwIndividualSoltVos>)entry.getValue();
                String tmpStr = "";
                Long sex = null;
                List<DocStructFragmentVo> listDocStructFragmentVo = new ArrayList<DocStructFragmentVo>();
                DocStructFragmentVo docStructFragmentVo = new DocStructFragmentVo();
                docStructFragmentVo.setNoumenonSoid(listTmp.get(0).getNoumenonSoid());
                //docStructFragmentVo.setNoumenonName(listTmp.get(0).getNoumenonName());
                docStructFragmentVo.setTagName(TAG_LABEL);
                List<DocStructTemplateSlotVo> listDocStructTemplateSlotVo = new ArrayList<DocStructTemplateSlotVo>();

                boolean flg = false;
                for (KnwIndividualSoltVos v :listTmp) {
                    DocStructTemplateSlotVo docStructTemplateSlotVo = setDocStructFragmentVoList(v);
                    // 检查类型的场合
                    if (v.getDerailCodingSystemSoid() != null
                            && v.getDerailCodingSystemSoid() == 1702l
                            && v.getDataSetSoid() != null) {
                        // 检查类型不一致的场合
                        if (mapExamServiceType.get(v.getDataSetSoid().toString()) == null) {
                            continue;
                            // 检查类型一致的场合
                        } else {
                            flg = true;
                        }
                    }

                    // 段落片段Slot对象追加
                    listDocStructTemplateSlotVo.add(docStructTemplateSlotVo);

                    // 影像诊断编码体系的场合
                    if (v.getDerailCodingSystemSoid() != null
                            &&  v.getDerailCodingSystemSoid() == 20197039698608128l) {
                        tmpStr = v.getIndividualName();
                        continue;
                    }

                    // 性别的场合
                    if (v.getDerailCodingSystemSoid() != null
                            && v.getDerailCodingSystemSoid() == 373l
                            && v.getDataSetSoid() != null) {
                        sex = v.getDataSetSoid();
                        continue;
                    }
                }
                docStructFragmentVo.setDocStructTemplateSlotVoList(listDocStructTemplateSlotVo);
                listDocStructFragmentVo.add(docStructFragmentVo);
                recommendDiagnosticVo.setDocStructFragmentVoList(listDocStructFragmentVo);
                if ((sex == null || sex == vo.getSexSoid()) && flg) {
                    recommendDiagnosticVo.setRecommendDiagnosticContent(tmpStr);
                    listRecommendDiagnosticVo.add(recommendDiagnosticVo);
                }
            }

            buildListSuccess(result, listRecommendDiagnosticVo);
        } catch (Exception e) {
            list = new ArrayList<KnwIndividualSoltVos>();
            log.error("取得推荐诊断列表异常",e);
            buildListWarn(result, "取得推荐诊断列表失败");
        } finally {
            stopWatch.stop();
            log.info("本次查询耗时: " + stopWatch.getTime() + "ms");
        }
        return result;
    }

    @Override
    public ListResult getRecommendDiagnosticList(Map<String, Object> map) {
        log.info("getRecommendDiagnosticList,查询条件: " + map.toString());
        ListResult result = new ListResult();
        List<KnwIndividualSoltVos> list = new ArrayList<KnwIndividualSoltVos>();
        StopWatch stopWatch = StopWatch.createStarted();
        try {
            list = knwIndividualSoltMapper.getRecommendDiagnosticList(map);
            buildListSuccess(result, list);
        } catch (Exception e) {
            log.error("getRecommendDiagnosticList异常",e);
            buildListWarn(result, "联系管理员");
        } finally {
            stopWatch.stop();
            log.info("本次查询耗时: " + stopWatch.getTime() + "ms");
        }

        return result;
    }

    /**
     * 根据部位soid、检查类型soid查询相关领域本体的soid
     *
     * @param vo
     * @return
     */
    @Override
    public ListResult getNoumenonDomainSoids(PatientInfoParameterVo vo) {
//        log.info("根据部位soid、检查类型soid查询相关领域本体的soid,查询条件: " + vo.toString());
//        ListResult result = new ListResult();
//        StopWatch stopWatch = StopWatch.createStarted();
//
//        List<BodyTreeVo> list = new ArrayList<BodyTreeVo>();
//        BodyTreeVo bodyTreeVo = new BodyTreeVo();
//        List<Long> longList = new ArrayList<>();
//        MediaImageFindDto mediaImageFindDto = new MediaImageFindDto();
//        try {
//            String[] str;
//            List<DataSet> listDataSet = new ArrayList<>();
//            List<Long> conceptSoids = new ArrayList<Long>();
//            if (StringUtils.isNotEmpty(vo.getBodySoid())) {
//                str = vo.getBodySoid().split(",");
//                List<String> lists = Arrays.asList(str);
//                List<Long> lList = new ArrayList<Long>();
//                for (String s :lists) {
//                    lList.add(Long.valueOf(s));
//                }
//
//                listDataSet = cMDetailCodingSystemMapper.getConceptSoids(lList);
//
//                if (listDataSet != null && listDataSet.size() > 0) {
//                    for (DataSet d : listDataSet) {
//                        conceptSoids.add(d.getConceptSoid());
//                    }
//                }
//
//            }
//
//            List<KnwNoumenonVo> knwNoumenonVos = new ArrayList<KnwNoumenonVo>();
//            if (conceptSoids != null && conceptSoids.size() > 0) {
//                knwNoumenonVos = knwNoumenonMapper.getKnwNoumenons(conceptSoids);
//            }
//
//            List<Long> conceptualSoids = new ArrayList<>();
//            List<Long> noumenonSoidsTmp = new ArrayList<>();
//            if (knwNoumenonVos != null && knwNoumenonVos.size() > 0) {
//                for (KnwNoumenonVo v:knwNoumenonVos) {
//                    if (v.getConceptualSoid() != null) {
//                        conceptualSoids.add(v.getConceptualSoid());
//                    }
//                    if (v.getCnt() >0) {
//                        noumenonSoidsTmp.add(v.getNoumenonSoid());
//                    }
//                }
//
//                List<BodyTreeVo> listTmp = new ArrayList<>();
//                if (noumenonSoidsTmp.size() > 0) {
//                    listTmp = knwNoumenonRelationMapper.getBodyTree(noumenonSoidsTmp);
//                }
//
//                if (listTmp != null && listTmp.size() > 0) {
//                    noumenonSoidsTmp = new ArrayList<>();
//                    for (BodyTreeVo bt :listTmp) {
//                        if (bt.getConceptualSoid() != null) {
//                            conceptualSoids.add(bt.getConceptualSoid());
//                        }
//                        if (bt.getCnt() > 0) {
//                            noumenonSoidsTmp.add(bt.getSourceNoumenonSoid());
//                        }
//                    }
//
//                    listTmp = new ArrayList<>();
//                    if (noumenonSoidsTmp.size() > 0) {
//                        listTmp = knwNoumenonRelationMapper.getBodyTree(noumenonSoidsTmp);
//                    }
//
//                    if (listTmp != null && listTmp.size() > 0) {
//                        noumenonSoidsTmp = new ArrayList<>();
//                        for (BodyTreeVo bt :listTmp) {
//                            if (bt.getConceptualSoid() != null) {
//                                conceptualSoids.add(bt.getConceptualSoid());
//                            }
//                            if (bt.getCnt() > 0) {
//                                noumenonSoidsTmp.add(bt.getSourceNoumenonSoid());
//                            }
//                        }
//                    }
//
//                    listTmp = new ArrayList<>();
//                    if (noumenonSoidsTmp.size() > 0) {
//                        listTmp = knwNoumenonRelationMapper.getBodyTree(noumenonSoidsTmp);
//                    }
//
//                    if (listTmp != null && listTmp.size() > 0) {
//                        noumenonSoidsTmp = new ArrayList<>();
//                        for (BodyTreeVo bt :listTmp) {
//                            if (bt.getConceptualSoid() != null) {
//                                conceptualSoids.add(bt.getConceptualSoid());
//                            }
//                            if (bt.getCnt() > 0) {
//                                noumenonSoidsTmp.add(bt.getSourceNoumenonSoid());
//                            }
//                        }
//                    }
//
//                }
//            }
//
//            List<Long> lists = new ArrayList<>();
//            if (conceptualSoids != null && conceptualSoids.size() > 0) {
//                lists = cMDetailCodingSystemMapper.getDataSetSoid(conceptualSoids);
//            }
//
//            Map<String, Object> mapParm = new HashMap<String, Object>();
//            mapParm.put("listConceptualSoid", conceptualSoids);
//            mapParm.put("type", vo.getExamServiceTypeSoid());
//            // 根据服务实例soid以及概念soid查询，相关领域本体下对应服务实例类型的本体soid
//            List<KnwNoumenonVo> listKnwNoumenonVo =
//                    knwNoumenonMapper.getKnwNoumenonList(mapParm);
//            Map<String, Object> map = new HashMap<String, Object>();
//            StringBuffer strBuff = new StringBuffer();
//            if (listKnwNoumenonVo != null && listKnwNoumenonVo.size() > 0 ) {
//                for (int i = 0; i < listKnwNoumenonVo.size(); i++) {
//                    if(i==0) {
//                        strBuff.append(listKnwNoumenonVo.get(i).getNoumenonSoid());
//                    } else {
//                        strBuff.append(",");
//                        strBuff.append(listKnwNoumenonVo.get(i).getNoumenonSoid());
//                    }
//                }
//            }
//
//            buildListSuccess(result, strBuff);
//        } catch (Exception e) {
//            list = new ArrayList<BodyTreeVo>();
//            log.error("根据部位soid、检查类型soid查询相关领域本体的soid异常",e);
//            buildListWarn(result, "根据部位soid、检查类型soid查询相关领域本体的soid失败");
//        } finally {
//            stopWatch.stop();
//            log.info("本次查询耗时: " + stopWatch.getTime() + "ms");
//        }
//        return result;
        return null;
    }

    /**
     *
     * @return
     */
    private DocStructTemplateSlotVo setDocStructFragmentVoList(KnwIndividualSoltVos v) {
        // 模板段落片段Slot
        DocStructTemplateSlotVo docStructTemplateSlotVo = new DocStructTemplateSlotVo();
        // 模板段落片段SlotValue
        DocStructSlotValueVo docStructSlotValueVo = new DocStructSlotValueVo();
        docStructSlotValueVo.setDataValue(v.getDataSetMeaning());

//        if (v.getDerailCodingSystemSoid() != null
//                &&  v.getDerailCodingSystemSoid() == 20197039698608128l) {
//            docStructTemplateSlotVo.setTagName("Taglabel");
//        }
        docStructTemplateSlotVo.setTagName(TAG_LABEL);
        docStructTemplateSlotVo.setDocStructSlotValueVo(docStructSlotValueVo);

        docStructTemplateSlotVo.setSlotSoid(v.getSlotSoid());
        docStructTemplateSlotVo.setIndividualSoid(v.getIndividualSoid());
        docStructTemplateSlotVo.setIndividualName(v.getIndividualName());
        docStructTemplateSlotVo.setNoumenonSoid(v.getNoumenonSoid());

        return docStructTemplateSlotVo;
    }
}
